iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 27
0

這邊的 EC 指的是 Electronic Commerce,也就是所謂的電子商務,我們將用一到兩章節的篇幅來介紹如何用 Gatsby 來建立一個基礎的電子商務網站,並串接 Stripe 來做付款的測試,但我們為什麼要用 Gatsby 來做電商?

因爲 Gatsby 擁有靜態網站的特點,安全性、性能提高、方便部署等優勢。

什麼是 Stripe

Stripe 是一項付款處理服務,可以讓我們安全且方便地處理客戶的付款資訊,我們非用它不可嗎?沒有,像是在台灣就蠻多家電商有提供這樣的服務,例如大家耳熟能詳的綠界、藍新、紅陽等等,只是便於此次文章測試,所以我們採用的是 Stripe。

Stripe 為我們處理了結帳這部分的功能,我們不需要建立任何的後端,我們只需要在 Stripe 提供的 Dashboard 上設定產品、SKUs 及我們訂閱的計畫,就可以輕易地使用這項服務。

在我們開始之前,記得先到 Stripe 註冊,以便後續我們能使用測試 API。

專案環境設置

同樣的,我們先在終端機上用 Gatsby CLI 來快速建置一個專案

gatsby new ecommerce-gatsby-tutorial

在專案建置完畢後,我們到專案目錄下執行以下指令來安裝 Stripe 套件

npm install gatsby-plugin-stripe

套件成功安裝完畢後,我們開啟 gatsby-config.js 來引入 Stripe,其他像是gatsby-plugin-react-helmet 或 gatsby-source-filesystem 等套件都是預設安裝的,我們只要在陣列最下方加入 gatsby-plugin-stripe 即可。

plugins: [
    `gatsby-plugin-react-helmet`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `images`,
        path: `${__dirname}/src/images`,
      },
    },
    `gatsby-transformer-sharp`,
    `gatsby-plugin-sharp`,
    {
      resolve: `gatsby-plugin-manifest`,
      options: {
        name: `gatsby-starter-default`,
        short_name: `starter`,
        start_url: `/`,
        background_color: `#663399`,
        theme_color: `#663399`,
        display: `minimal-ui`,
        icon: `src/images/gatsby-icon.png`, // This path is relative to the root of the site.
      },
    },
    "gatsby-plugin-stripe"
  ],

設定完畢後,我們打開開發伺服器看看有沒有成功添加套件。

開啟後,我們連入 http://localhost:8000 中,會看到以下預設畫面,這時我們搜尋套件幫我們加載的 Script,如下圖右側紅框處,就代表我們成功的載入套件了。

<script src="https://js.stripe.com/v3/"></script>

https://ithelp.ithome.com.tw/upload/images/20201012/20109495jOka2OWtXx.png

完成後,我們連到 Stripe 的 Dashboard,並且點擊右側的開發者 -> API Key,這時你的右側應該會如下圖般,我們待會會需要用到 Public Key 與 Private Key 來通過 API 的驗證。

Private Key 非常重要,需要讀者們保管好,如果讓其他人拿到這組 Key ,他們可以查看你所發出的任何請求、費用與購買相關的資訊,甚至能退款給客戶,所以這組 Key 不應該會放到 GitHub 或前端的程式碼中。

https://ithelp.ithome.com.tw/upload/images/20201012/20109495RF5UvNViFD.png

取得 Key 後,我們點擊產品欄位並快速的新增一個商品,因為我們會需要產品的 SKU 且我們在送需求給 API 時,API 也會驗證我們的資訊是否正確。

新增完產品後,我們開啟 src/components 目錄,並在目錄下新增一支 checkout.js ,裡面我們建置一個結帳元件,如下方程式碼。

import React from "react"

// 給結帳按鈕設定樣式
const buttonStyles = {
  fontSize: "13px",
  textAlign: "center",
  color: "#fff",
  outline: "none",
  padding: "12px 60px",
  boxShadow: "2px 5px 10px rgba(0,0,0,.1)",
  backgroundColor: "rgb(255, 178, 56)",
  borderRadius: "6px",
  letterSpacing: "1.5px",
}

// 使用 Class Component 的方式來建立元件
const Checkout = class extends React.Component {
  // 在頁面第一次載入 DOM 的時間點時,初始化 Stripe
  componentDidMount() {
    // 這邊會設定我們的 Key
    this.stripe = window.Stripe("pk_test_jG9s3XMdSjZF9Kdm5g59zlYd")
  }

	// 驗證我們的資訊,成功便發出請求,失敗也會做錯誤的處理
  async redirectToCheckout(event) {
    event.preventDefault()
    const { error } = await this.stripe.redirectToCheckout({
      // 放置 sku
      items: [{ sku: "sku_DjQJN2HJ1kkvI3", quantity: 1 }],
      successUrl: `http://localhost:8000/page-2/`,
      cancelUrl: `http://localhost:8000/`,
    })

    if (error) {
      console.warn("Error:", error)
    }
  }

  render() {
	  // 回傳對應的 JSX 結構
    return (
      <button
        style={buttonStyles}
        onClick={event => this.redirectToCheckout(event)}
      >
        購買
      </button>
    )
  }
}

export default Checkout

關於生命週期,有興趣的讀者可以參考 Life Cycle - Ian Chu 這篇,另外如果對於 Functional Component 的生命週期寫法有興趣的讀者,則可以參考 useEffect Hook - React 這篇

我們新增完結帳按鈕後,接著我們要到首頁中去引用它,來測試我們的成果,
打開 pages 目錄下的 index.js ,並引入以下程式碼

import Checkout from "../components/checkout"

接著我們將 Checkout 元件放置在任意位置上,然後我們重啟開發伺服器,你會看到畫面中有個黃色抖大的購買按鈕,點擊下去後

https://ithelp.ithome.com.tw/upload/images/20201012/20109495QxVFRc6M2N.png

我們應該能看到以下結帳畫面

https://ithelp.ithome.com.tw/upload/images/20201012/20109495ZROhVUE3oj.png

今天我們初步的完成了一個結帳的流程,但還記得嗎?我們上面有提到不要將 Key 放在前端或 GitHub 上分享,而目前,我們將 Key 的資訊都放在了 CheckOut 的元件當中,所以明天我們會用其他方式來解決這個不安全的問題,各位讀者,我們明天見!

參考資料

Gatsby E-commerce Tutorial - Gatsby


上一篇
[Day 26] - Gatsby feat. WordPress
下一篇
[Day 28] - Gatsby feat. EC ( 下 )
系列文
雖然你不是木村拓哉,但它也可以讓你變很行 - Gatsby.js30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言